#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <mutex>
#include <cassert>
#include <algorithm>

#include "oj_model.cpp";
#include "oj_view.hpp";
#include "../Comm/log.hpp";
#include "../Comm/util.hpp"

namespace ns_control
{
    using namespace std;
    using namespace ns_model;
    using namespace ns_view;
    using namespace ns_util;
    using namespace ns_log;

    class Machine
    {
    public:
        std::string _ip;
        int _port;
        uint64_t _load;
        std::mutex *_mtx; // mutex禁止拷贝！！！
    public:
        Machine()
            : _ip(""), _port(0), _load(0), _mtx(nullptr)
        {
        }
        ~Machine()
        {
        }
    };

    // 负载均衡模块，
    const std::string service_machine = "./conf/service_machine.conf";
    class LoadBlance
    {
    public:
        LoadBlance()
        {
            assert(LoadConf(service_machine));
            LOG(INFO) << "加载" << service_machine << "成功！！" << "\n";
        }
        ~LoadBlance()
        {
        }

    public:
        bool LoadConf(const std::string &machine_conf)
        {
            std::ifstream in(machine_conf);
            if (!in.is_open())
            {
                LOG(FATLE) << "加载" << service_machine << "成功！！" << "\n";
                return false;
            }

            std::string line;
            while (std::getline(in, line))
            {
                std::vector<std::string> tokens;
                StringUtil::SplitString(line, &tokens, " ");
                if (tokens.size() != 2)
                {
                    LOG(WARNINR) << "切分" << line << "失败" << "\n";
                    continue;
                }
                Machine m;
                m._ip = tokens[0];
                m._port = atoi(tokens[1].c_str());
                m._load = 0;
                m._mtx = new std::mutex();

                _online.push_back(_machines.size());
                _machines.push_back(m);
            }

            in.close();
            return true;
        }

    private:
        vector<Machine> _machines; // hash映射，下标充当当前主机id, 索引服务机器
        vector<int> _online;       // 在线主机
        vector<int> _offline;      // 离线主机
    };

    // 核心业务 控制逻辑模块
    class Control
    {
    private:
        Model _model;
        View _view;

    public:
        Control()
        {
        }
        ~Control()
        {
        }

    public:
        bool AllQuestion(std::string *html)
        {
            bool ret = true;
            vector<struct Question> all;
            if (!_model.GetAllQuestions(&all))
            {
                sort(all.begin(), all.end(), [](const struct Question &q1, const struct Question &q2)
                     { return atoi(q1.number.c_str()) < atoi(q2.number.c_str()); });
                _view.AllExpandHtml(all, html);
            }
            else
            {
                *html = "获取题目失败, 形成题目列表失败";
                ret = false;
            }
            return ret;
        }

        bool OneQuestion(const std::string &number, std::string *html)
        {
            bool ret = true;
            struct Question q;
            if (!_model.GetOneQuestion(number, &q))
            {
                _view.OneExpandHtml(q, html);
            }
            else
            {
                *html = "指定题目 " + number + "不存在！";
                return ret;
            }
            return ret;
        }
    };
}